package com.credithc.customers.manager.service.impl;

import com.credithc.baseserv.pageHelper.PageInfo;
import com.credithc.customers.base.constants.CustomerConstants;
import com.credithc.customers.base.factory.DictionaryFactory;
import com.credithc.customers.base.mapper.CustomerAddFlowMapper;
import com.credithc.customers.base.mapper.CustomerContactFlowMapper;
import com.credithc.customers.base.po.CustomerAddFlowPo;
import com.credithc.customers.base.po.CustomerContactFlowPo;
import com.credithc.customers.base.service.ICacheService;
import com.credithc.customers.base.utils.CustomerUtils;
import com.credithc.customers.manager.echarts.CustomerModifyAddLine;
import com.credithc.customers.manager.echarts.CustomerModifyAddPie;
import com.credithc.customers.manager.mapper.EChartsMapper;
import com.credithc.customers.manager.po.CustomerModifyPiePo;
import com.credithc.customers.manager.po.CustomerModifyPo;
import com.credithc.customers.manager.ro.CustomerModifyRo;
import com.credithc.customers.manager.ro.HomeRo;
import com.credithc.customers.manager.service.DesensitizationService;
import com.credithc.customers.manager.service.ICustomerModifyService;
import com.credithc.customers.manager.utils.StatsUtils;
import com.credithc.customers.manager.vo.CustomerModifyVo;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.util.*;

/**
 * @author zhukai
 * @date 2018/12/17 17:34
 */
@Service
public class CustomerModifyServiceImpl implements ICustomerModifyService {

    private final CustomerContactFlowMapper contactFlowMapper;

    private final CustomerAddFlowMapper addFlowMapper;

    private final EChartsMapper eChartsMapper;

    private final DesensitizationService desensitizationService;

    private final ICacheService cacheService;

    @Autowired
    public CustomerModifyServiceImpl(CustomerContactFlowMapper contactFlowMapper, CustomerAddFlowMapper addFlowMapper, EChartsMapper eChartsMapper, DesensitizationService desensitizationService, ICacheService cacheService) {
        this.contactFlowMapper = contactFlowMapper;
        this.addFlowMapper = addFlowMapper;
        this.eChartsMapper = eChartsMapper;
        this.desensitizationService = desensitizationService;
        this.cacheService = cacheService;
    }

    @Override
    public Map<String, PageInfo> getModifyList(CustomerModifyRo ro) {
        Map<String, PageInfo> map = new HashMap<>(1);
        int currentPage = 1, perPageSize = 20;
        if (ro.getPageNo() != null && ro.getPageNo() > 0) {
            currentPage = ro.getPageNo();
        }
        if (ro.getPageSize() != null && ro.getPageSize() > 0) {
            perPageSize = ro.getPageSize();
        }
        if ("contact".equals(ro.getModifyType())) {
            if ("add".equals(ro.getModifyMethod())) {
                map.put("pageInfo", getContactAddPageInfo(ro, currentPage, perPageSize));
            } else if ("modify".equals(ro.getModifyMethod())) {
                map.put("pageInfo", getContactModifyPageInfo(ro, currentPage, perPageSize));
            }
        } else if ("id".equals(ro.getModifyType())) {
            if ("add".equals(ro.getModifyMethod())) {
                map.put("pageInfo", getIdAddPageInfo(ro, currentPage, perPageSize));
            } else if ("modify".equals(ro.getModifyMethod())) {
                map.put("pageInfo", getIdModifyPageInfo(ro, currentPage, perPageSize));
            }
        }
        return map;
    }

    @Override
    public Map<String, String> statsModify(String type, String statsType, String dateType) {
        Map<String, String> map = new HashMap<>(1);
        if ("contactInfo".equals(type)) {
            if ("line".equals(statsType)) {
                map.put("contactLine", generateContactLine(dateType));
            } else {
                map.put("contactLine", generateContactLine(dateType));
                map.put("contactPie", generateContactPie());
            }
        } else {
            if ("line".equals(statsType)) {
                map.put("idLine", generateIdLine(dateType));
            } else {
                map.put("idLine", generateIdLine(dateType));
                map.put("idPie", generateIdPie());
            }
        }
        return map;
    }

    private String generateContactLine(String dateType) {
        if (StringUtils.isBlank(dateType)) {
            dateType = "week";
        }
        List<String> list = StatsUtils.generateXAxisList(null, null, dateType);
        HomeRo ro = new HomeRo();
        ro.setCustomerStateDateStart(list.get(0));
        ro.setCustomerStateDateEnd(list.get(list.size() - 1));
        List<CustomerModifyPo> pos = eChartsMapper.statsContactCount(ro);
        CustomerModifyAddLine customerModifyAddLine = new CustomerModifyAddLine(pos, list);
        return customerModifyAddLine.generateGraph();
    }

    private String generateContactPie() {
        List<CustomerModifyPiePo> pos = eChartsMapper.statsContactModifyCountBySystem();
        List<String> colList = new ArrayList<>();
        for (CustomerModifyPiePo po : pos) {
            colList.add(po.getSystem());
        }
        CustomerModifyAddPie customerModifyAddPie = new CustomerModifyAddPie(pos, colList);
        return customerModifyAddPie.generateGraph();
    }

    private String generateIdLine(String dateType) {
        if (StringUtils.isBlank(dateType)) {
            dateType = "week";
        }
        List<String> list = StatsUtils.generateXAxisList(null, null, dateType);
        HomeRo ro = new HomeRo();
        ro.setCustomerStateDateStart(list.get(0));
        ro.setCustomerStateDateEnd(list.get(list.size() - 1));
        List<CustomerModifyPo> pos = eChartsMapper.statsIdCount(ro);
        CustomerModifyAddLine customerModifyAddLine = new CustomerModifyAddLine(pos, list);
        return customerModifyAddLine.generateGraph();
    }

    private String generateIdPie() {
        List<CustomerModifyPiePo> pos = eChartsMapper.statsIdModifyCountBySystem();
        List<String> colList = new ArrayList<>();
        for (CustomerModifyPiePo po : pos) {
            colList.add(po.getSystem());
        }
        CustomerModifyAddPie customerModifyAddPie = new CustomerModifyAddPie(pos, colList);
        return customerModifyAddPie.generateGraph();
    }

    private PageInfo<CustomerModifyVo> getContactAddPageInfo(CustomerModifyRo ro, int currentPage, int perPageSize) {
        Example example = new Example(CustomerAddFlowPo.class);
        example.setOrderByClause("create_time DESC");
        generateContactConditions(example, ro, true);
        Page<CustomerAddFlowPo> page = PageHelper.startPage(currentPage, perPageSize);
        List<CustomerAddFlowPo> pos = addFlowMapper.selectByExample(example);
        List<CustomerModifyVo> vos = new ArrayList<>();
        generateAddInfoList(pos, vos);
        desensitizationService.desensitizationList(vos);
        return new PageInfo(vos, (int) page.getTotal(), currentPage, perPageSize);
    }

    private PageInfo<CustomerModifyVo> getIdAddPageInfo(CustomerModifyRo ro, int currentPage, int perPageSize) {
        Example example = new Example(CustomerAddFlowPo.class);
        // Example.Criteria criteria = example.createCriteria();
        example.setOrderByClause("create_time DESC");
        generateIdConditions(example, ro, true);

        Page<CustomerAddFlowPo> page = PageHelper.startPage(currentPage, perPageSize);
        List<CustomerAddFlowPo> pos = addFlowMapper.selectByExample(example);
        List<CustomerModifyVo> vos = new ArrayList<>();
        generateAddInfoList(pos, vos);
        desensitizationService.desensitizationList(vos);
        return new PageInfo(vos, (int) page.getTotal(), currentPage, perPageSize);
    }

    private void generateAddInfoList(List<CustomerAddFlowPo> pos, List<CustomerModifyVo> vos) {
        for (CustomerAddFlowPo po : pos) {
            CustomerModifyVo vo = new CustomerModifyVo();
            BeanUtils.copyProperties(po, vo);
            vo.setSystemSign(cacheService.getSystemNameBySign(po.getSystemSign()));
            vo.setSubSystemSign(cacheService.getSystemNameBySign(po.getSubSystemSign()));
            vo.setCreateTime(CustomerUtils.timestamp2Stirng(po.getCreateTime()));
            vo.setContactType(getConcatTypeStr(po.getContactType()));
            vo.setIdCardType(getIdTypeStr(po.getIdCardType()));
            vo.setElementsVerified(getElementVerified(po.getElementsVerified()));
            vos.add(vo);
        }
    }

    private PageInfo<CustomerModifyVo> getContactModifyPageInfo(CustomerModifyRo ro, int currentPage, int perPageSize) {
        Example example = new Example(CustomerContactFlowPo.class);
        example.setOrderByClause("create_time DESC");
        generateContactConditions(example, ro, false);
        Page<CustomerContactFlowPo> page = PageHelper.startPage(currentPage, perPageSize);
        List<CustomerContactFlowPo> pos = contactFlowMapper.selectByExample(example);
        List<CustomerModifyVo> vos = new ArrayList<>();
        for (CustomerContactFlowPo po : pos) {
            CustomerModifyVo vo = new CustomerModifyVo();
            BeanUtils.copyProperties(po, vo);
            vo.setSystemSign(cacheService.getSystemNameBySign(po.getSystemSign()));
            vo.setSubSystemSign(cacheService.getSystemNameBySign(po.getSubSystemSign()));
            vo.setCreateTime(CustomerUtils.timestamp2Stirng(po.getCreateTime()));
            vo.setContactType(getConcatTypeStr(po.getContactType()));
            vo.setContactTypeOld(getConcatTypeStr(po.getContactTypeOld()));
            vos.add(vo);
        }
        desensitizationService.desensitizationList(vos);
        return new PageInfo(vos, (int) page.getTotal(), currentPage, perPageSize);
    }

    private PageInfo<CustomerModifyVo> getIdModifyPageInfo(CustomerModifyRo ro, int currentPage, int perPageSize) {
        Example example = new Example(CustomerContactFlowPo.class);
        example.setOrderByClause("create_time DESC");
        generateIdConditions(example, ro, false);
        Page<CustomerContactFlowPo> page = PageHelper.startPage(currentPage, perPageSize);
        List<CustomerContactFlowPo> pos = contactFlowMapper.selectByExample(example);
        List<CustomerModifyVo> vos = new ArrayList<>();
        for (CustomerContactFlowPo po : pos) {
            CustomerModifyVo vo = new CustomerModifyVo();
            vo.setId(po.getId());
            vo.setCustomerNo(po.getCustomerNo());
            vo.setCustomerName(po.getCustomerName());
            vo.setIdCardType(getIdTypeStr(po.getContactType()));
            vo.setIdCardNo(po.getContactInfo());
            vo.setCustomerNameOld(po.getCustomerNameOld());
            vo.setIdCardTypeOld(getIdTypeStr(po.getContactTypeOld()));
            vo.setIdCardNoOld(po.getContactInfoOld());
            vo.setCreateTime(CustomerUtils.timestamp2Stirng(po.getCreateTime()));
            Map<String, String> noticeStatusMap = DictionaryFactory.Dict.NOTICE_STATUS.getDictMap();
            if (po.getNoticeStatus() != null) {
                vo.setNoticeStatus(noticeStatusMap.get(po.getNoticeStatus().toString()));
            }
            vo.setSubSystemSign(cacheService.getSystemNameBySign(po.getSubSystemSign()));
            vos.add(vo);
        }
        desensitizationService.desensitizationList(vos);
        return new

                PageInfo(vos, (int) page.

                getTotal(), currentPage, perPageSize);
    }

    private Example generateContactConditions(Example example, CustomerModifyRo ro, boolean isAdd) {
        example.setDistinct(false);
        Example.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(ro.getContactInfo())) {
            criteria.andEqualTo("contactInfo", ro.getContactInfo());
        }
        generateTimeConditions(criteria, ro);
        if (isAdd) {
            criteria.andIn("type", Arrays.asList(1, 3));
        } else {
            criteria.andEqualTo("modifyType", "1");
        }
        return example;
    }

    private Example generateIdConditions(Example example, CustomerModifyRo ro, boolean isAdd) {
        example.setDistinct(false);
        Example.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(ro.getCustomerName())) {
            criteria.andEqualTo("customerName", ro.getCustomerName());
        }
        if (isAdd) {
            if (StringUtils.isNotBlank(ro.getIdCardNo())) {
                criteria.andEqualTo("idCardNo", ro.getIdCardNo());
            }
            criteria.andIn("type", Arrays.asList(2, 3));
        } else {
            if (StringUtils.isNotBlank(ro.getIdCardNo())) {
                criteria.andEqualTo("contactInfo", ro.getIdCardNo());
            }
            criteria.andEqualTo("modifyType", "2");
        }
        if (ro.getNoticeStatus() != null) {
            criteria.andEqualTo("noticeStatus", ro.getNoticeStatus());
        }
        generateTimeConditions(criteria, ro);
        return example;
    }

    private Example.Criteria generateTimeConditions(Example.Criteria criteria, CustomerModifyRo ro) {
        if (StringUtils.isNotBlank(ro.getCustomerNo())) {
            criteria.andEqualTo("customerNo", ro.getCustomerNo());
        }
        if (StringUtils.isNotBlank(ro.getStartDate()) && StringUtils.isNotBlank(ro.getEndDate())) {
            criteria.andBetween("createTime", ro.getStartDate(), ro.getEndDate());
        } else if (StringUtils.isNotBlank(ro.getStartDate())) {
            criteria.andGreaterThanOrEqualTo("createTime", ro.getStartDate());
        } else if (StringUtils.isNotBlank(ro.getEndDate())) {
            criteria.andLessThanOrEqualTo("createTime", ro.getStartDate());
        }
        criteria.andEqualTo("status", CustomerConstants.STATUS_SUCCESS);
        return criteria;
    }

    private String getConcatTypeStr(String key) {
        if (StringUtils.isBlank(key)) {
            return null;
        }
        Map<String, String> contactTypeMap = DictionaryFactory.Dict.CONTACT_TYPE.getDictMap();
        return contactTypeMap.get(key);
    }

    private String getIdTypeStr(String key) {
        if (StringUtils.isBlank(key)) {
            return null;
        }
        Map<String, String> contactTypeMap = DictionaryFactory.Dict.ID_TYPE.getDictMap();
        return contactTypeMap.get(key);
    }

    private String getElementVerified(String key) {
        if (StringUtils.isBlank(key)) {
            return null;
        }
        Map<String, String> verifiedMap = DictionaryFactory.Dict.ELEMENTS_STATUS.getDictMap();
        return verifiedMap.get(key);

    }

}
